package service

import (
	"context"
	"errors"
	"fmt"
	"gitee.com/chunanyong/logger"
	"gitee.com/chunanyong/zorm"
	"zorm-learn/app/auth/model"
	"zorm-learn/app/util"
)

// SaveUsersStruct 保存
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func SaveUsersStruct(ctx context.Context, usersstruct *model.UsersStruct) error {

	// usersstruct对象指针不能为空
	if usersstruct == nil {
		return errors.New("usersstruct对象指针不能为空")
	}
	//匿名函数return的error如果不为nil,事务就会回滚
	_, errSaveUsersStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始

		_, errSaveUsersStruct := zorm.Insert(ctx, usersstruct)

		if errSaveUsersStruct != nil {
			return nil, errSaveUsersStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errSaveUsersStruct != nil {
		errSaveUsersStruct := fmt.Errorf("service.SaveUsersStruct错误:%w", errSaveUsersStruct)
		logger.Error(errSaveUsersStruct)
		return errSaveUsersStruct
	}

	return nil
}

// UpdateUsersStruct 更新
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateUsersStruct(ctx context.Context, usersstruct *model.UsersStruct) error {

	// usersstruct对象指针或主键Id不能为空
	if usersstruct == nil {
		return errors.New("usersstruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateUsersStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateUsersStruct := zorm.Update(ctx, usersstruct)

		if errUpdateUsersStruct != nil {
			return nil, errUpdateUsersStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateUsersStruct != nil {
		errUpdateUsersStruct := fmt.Errorf("service.UpdateUsersStruct错误:%w", errUpdateUsersStruct)
		logger.Error(errUpdateUsersStruct)
		return errUpdateUsersStruct
	}

	return nil
}

// UpdateNotZeroUsersStruct 更新
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateNotZeroUsersStruct(ctx context.Context, usersstruct *model.UsersStruct) error {

	// usersstruct对象指针或主键Id不能为空
	if usersstruct == nil {
		return errors.New("usersstruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateUsersStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateUsersStruct := zorm.UpdateNotZeroValue(ctx, usersstruct)

		if errUpdateUsersStruct != nil {
			return nil, errUpdateUsersStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateUsersStruct != nil {
		errUpdateUsersStruct := fmt.Errorf("service.UpdateNotZeroUsersStruct错误:%w", errUpdateUsersStruct)
		logger.Error(errUpdateUsersStruct)
		return errUpdateUsersStruct
	}

	return nil
}

// DeleteUsersStructById 根据Id删除
// 如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
// 如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
// 如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
// 但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func DeleteUsersStructById(ctx context.Context, id string) error {

	//id不能为空
	if len(id) < 1 {
		return errors.New("id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errDeleteUsersStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		finder := zorm.NewDeleteFinder(model.UsersStructTableName).Append(" WHERE id=?", id)
		_, errDeleteUsersStruct := zorm.UpdateFinder(ctx, finder)

		if errDeleteUsersStruct != nil {
			return nil, errDeleteUsersStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errDeleteUsersStruct != nil {
		errDeleteUsersStruct := fmt.Errorf("service.DeleteUsersStruct错误:%w", errDeleteUsersStruct)
		logger.Error(errDeleteUsersStruct)
		return errDeleteUsersStruct
	}

	return nil
}

// FindUsersStructById 根据Id查询信息
// ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindUsersStructById(ctx context.Context, id string) (*model.UsersStruct, error) {
	//id不能为空
	if len(id) < 1 {
		return nil, errors.New("id不能为空")
	}

	//根据Id查询
	finder := zorm.NewSelectFinder(model.UsersStructTableName).Append(" WHERE id=?", id)
	usersstruct := model.UsersStruct{}
	has, errFindUsersStructById := zorm.QueryRow(ctx, finder, &usersstruct)

	//记录错误
	if errFindUsersStructById != nil {
		errFindUsersStructById := fmt.Errorf("service.FindUsersStructById错误:%w", errFindUsersStructById)
		logger.Error(errFindUsersStructById)
		return nil, errFindUsersStructById
	}

	if !has {
		return nil, nil
	}

	return &usersstruct, nil

}

// FindUsersStructList 根据Finder查询列表
// ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindUsersStructList(ctx context.Context, finder *zorm.Finder, page *zorm.Page) ([]model.UsersStruct, error) {

	//finder不能为空
	if finder == nil {
		return nil, errors.New("finder不能为空")
	}

	usersstructList := make([]model.UsersStruct, 0)
	errFindUsersStructList := zorm.Query(ctx, finder, &usersstructList, page)

	//记录错误
	if errFindUsersStructList != nil {
		errFindUsersStructList := fmt.Errorf("service.FindUsersStructList错误:%w", errFindUsersStructList)
		logger.Error(errFindUsersStructList)
		return nil, errFindUsersStructList
	}

	return usersstructList, nil
}
func FindByPassword(ctx context.Context, auth string) (*model.UsersStruct, error) {
	if len(auth) < 1 {
		return nil, errors.New("auth 不能为空")
	}

	finder := zorm.NewSelectFinder(model.UsersStructTableName).Append(" WHERE PASSWORD=?", auth)
	usersstruct := model.UsersStruct{}
	has, err := zorm.QueryRow(ctx, finder, &usersstruct)

	//记录错误
	if err != nil {
		util.MainCtx.Logger.Error("service.FindUsersStructById错误:" + err.Error())
		return nil, err
	}

	if !has {
		return nil, nil
	}

	return &usersstruct, nil

}
